using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using QFramework.Example.Scripts.Event;
using QFramework.Example.Scripts.Model;
using UnityEngine;

namespace QFramework.Example.Scripts.System
{
    public interface IAchievementSystem : ISystem
    {
    }

    public class AchievementItem
    {
        public string Name { get; set; }
        public Func<bool> CheckComplete { get; set; }
        public bool Unlocked { get; set; }
    }

    public class AchievementSystem : AbstractSystem, IAchievementSystem
    {
        private readonly List<AchievementItem> _items = new();

        private bool _missed;

        protected override void OnInit()
        {
            this.RegisterEvent<OnMissEvent>(e => { _missed = true; });

            this.RegisterEvent<GameStartEvent>(e => { _missed = false; });

            _items.Add(new AchievementItem
            {
                Name = "百分成就",
                CheckComplete = () => this.GetModel<IGameModel>().BestScore.Value > 100
            });

            _items.Add(new AchievementItem
            {
                Name = "手残",
                CheckComplete = () => this.GetModel<IGameModel>().BestScore.Value < 0
            });

            _items.Add(new AchievementItem
            {
                Name = "零失误成就",
                CheckComplete = () => !_missed
            });

            _items.Add(new AchievementItem
            {
                Name = "全成就",
                CheckComplete = () =>
                {
                    var num = 0;
                    _items.ForEach(item =>
                    {
                        if (item.Unlocked) num++;
                    });
                    return num >= 3;
                }
            });

            // 成就系统一般是持久化的，所以如果需要持久化也是在这个时机进行，可以让 Unlocked 变成 BindableProperty
            this.RegisterEvent<GamePassEvent>(async e =>
            {
                await Task.Delay(TimeSpan.FromSeconds(0.1f));

                foreach (var achievementItem in _items)
                    if (!achievementItem.Unlocked && achievementItem.CheckComplete())
                    {
                        achievementItem.Unlocked = true;
                        Debug.Log("解锁 成就:" + achievementItem.Name);
                    }
            });
        }
    }
}